package readData;

import Types.DDI;
import Types.DrugDDIFile;
import Types.Entity;
import Types.Sentence;
import java.io.File;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class Reading {

    public Reading() {
    }

    public List<DrugDDIFile> readFromDir(String path, String source) {
        List<DrugDDIFile> files = new ArrayList();
        String pathErr = "";
        try {
            File folder = new File(path);
            File[] listOfFiles = folder.listFiles();
            for (int i = 0; i < listOfFiles.length; i++) {
                if (listOfFiles[i].isFile()) {
                    if (!listOfFiles[i].getName().equalsIgnoreCase(".DS_Store")) {
                        pathErr = path + listOfFiles[i].getName();
                        if (listOfFiles[i].getName().indexOf("~") < 0) {
                            files.add(readOneFile(path, listOfFiles[i].getName(), source));
                        }
                    }
                }
            }
        } catch (Throwable t) {
            System.out.println("Error in readFromDir");
            System.out.println(pathErr);
        }
        return files;
    }

    public List<Sentence> returnAllSent() {
        List<Sentence> Sent = new LinkedList<Sentence>();
        try {
            List<DrugDDIFile> files = readFromDir("/Users/majidrastegar-mojarad/UWM/ddiextractor/bin/Train/DrugBank/", "DrugBank");
            for (int i = 0; i < files.size(); i++) {
                Sent.addAll(files.get(i).getLstSentence());
            }

        } catch (Throwable t) {
            System.out.println("Error in returnAllSent");
        }
        return Sent;
    }

    public DrugDDIFile readOneFile(String path, String name, String source) {
        DrugDDIFile file = new DrugDDIFile(name, source);
        try {
            List<Sentence> sent = readFromFile(path + name);
            file.setistSentence(sent);
        } catch (Throwable t) {
        }
        return file;
    }

    public List<Sentence> readFromFile(String path) {
        List<Sentence> lstSentence = new ArrayList();
        try {
            DocumentBuilderFactory DBF = DocumentBuilderFactory.newInstance();
            DocumentBuilder DB = DBF.newDocumentBuilder();
            Document Doc = DB.parse(path);//gives fatal error: [Fatal Error] DDIunified2.dtd:1:3: The markup in the document preceding the root element must be well-formed.
            Doc.getDocumentElement().normalize();
            NodeList NL = Doc.getElementsByTagName("sentence");
            for (int i = 0; i < NL.getLength(); i++) {
                Sentence sen = new Sentence();
                Element tem = (Element) NL.item(i);
                sen.setId(tem.getAttribute("id"));
                sen.setText(tem.getAttribute("text"));
                sen = readingOneSent(sen, NL.item(i));
                if (sen != null) {
                    lstSentence.add(sen);
                }
            }
        } catch (Throwable t) {
        }
        return lstSentence;
    }

    private Sentence readingOneSent(Sentence sent, Node n) {
        try {
            if (n.getNodeType() == Node.ELEMENT_NODE) {
                Element el = (Element) n;

                NodeList nodeList = el.getElementsByTagName("entity");
                List<Entity> entList = new LinkedList<Entity>();
                for (int i = 0; i < nodeList.getLength(); i++) {
                    entList.add(readingOneEntity(nodeList.item(i)));
                }

                sent.setEntitiesList(entList);

                List<DDI> ddiList = new LinkedList<DDI>();
                nodeList = el.getElementsByTagName("ddi");
                for (int i = 0; i < nodeList.getLength(); i++) {
                    ddiList.add(readingOneDDI(nodeList.item(i)));
                }

                //save the sentence only if it has zero or one DDI
                //if (ddiList.size() != 1) {
                if (ddiList.size() > 1) {
                    return null;
                }

                String idFi, idSe;
                for (int i = 0; i < ddiList.size(); i++) {
                    idFi = ddiList.get(i).getId_firstEnt();
                    idSe = ddiList.get(i).getId_secondEnt();
                    for (int j = 0; j < entList.size(); j++) {
                        if (entList.get(j).getId().equalsIgnoreCase(idFi)) {
                            ddiList.get(i).setFirstEnt(entList.get(j));
                        }
                        if (entList.get(j).getId().equalsIgnoreCase(idSe)) {
                            ddiList.get(i).setSecondEnt(entList.get(j));
                        }
                    }
                }

                sent.setDdiList(ddiList);
            }
        } catch (Throwable t) {
        }
        return sent;
    }

    private Entity readingOneEntity(Node n) {
        Entity ent = new Entity();
        try {
            Element tem = (Element) n;
            ent.setId(tem.getAttribute("id"));
            ent.setText(tem.getAttribute("text"));
            ent.setCharOffset(tem.getAttribute("charOffset"));
            ent.setType(tem.getAttribute("type"));
        } catch (Throwable t) {
        }
        return ent;
    }

    private DDI readingOneDDI(Node n) {
        DDI di = new DDI();
        try {
            Element tem = (Element) n;
            di.setId(tem.getAttribute("id"));
            di.setId_firstEnt(tem.getAttribute("e1"));
            di.setId_secondEnt(tem.getAttribute("e2"));
            di.setType_text(tem.getAttribute("type"));
        } catch (Throwable t) {
        }
        return di;
    }
}
